package com.project.pet.security;

import com.alibaba.fastjson.JSONObject;
import com.project.pet.pojo.User;
import com.project.pet.service.UserService;
import com.project.pet.utils.JwtTokenUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.concurrent.atomic.AtomicReference;

@Component
public class SecurityFilter extends OncePerRequestFilter {
    @Autowired
    private JwtTokenUtils jwtTokenUtils;


    @Autowired
    private AuthenticationManager authenticationManager;

    @Autowired
    private UserService userService;

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        response.setCharacterEncoding("utf-8");
        String uri = request.getRequestURI();
        if(uri.equals("/api/web/user/login")
           || uri.equals("/api/web/user/register")
           || uri.startsWith("/files/")
            || uri.startsWith("/api/wx/user/login")
                || uri.startsWith("/api/wx/user/wxUserIfRegister")
        ){
            filterChain.doFilter(request,response);
            return;
        }
        String token = request.getHeader("Authorization");
        if(uri.startsWith("/api/web/") && StringUtils.isEmpty(token)){
            filterChain.doFilter(request,response);
            return;
        }
        if(uri.startsWith("/api/web/")){
            String userId = jwtTokenUtils.getUserIdFromToken(token);
            AtomicReference<User> user = new AtomicReference<>();
            jwtTokenUtils.getClaimFromToken(token,(map)->{
                user.set(JSONObject.parseObject(JSONObject.toJSONString(map), User.class));
                return null;
            });

            //这里存在问题，用户名和密码没有校验。（这里从token解析出来的密码是加密的）
            //进行校验
            UserDetails userDetails = userService.loadUserByUsername(user.get().getUsername());
            if(!userDetails.getPassword().equals(user.get().getPassword())){
                //这里只要抛出异常就能被ErrorAuthenticationEntryPoint捕获
                throw new IOException();
            }
            UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(
                    userDetails, null, userDetails.getAuthorities());
            authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));

            SecurityContextHolder.getContext().setAuthentication(authentication);
            filterChain.doFilter(request,response);
            return;
        }
        if(uri.startsWith("/api/wx/")){
            try{
                String wxUserId = jwtTokenUtils.getUserIdFromToken(token);
                request.setAttribute("wxUserId",wxUserId);
                filterChain.doFilter(request,response);
                return;
            }catch (Exception e){
                e.printStackTrace();
                response.setStatus(401);
                return;
            }
        }
        filterChain.doFilter(request,response);
    }
}
